package com.cloud.phone.websocket;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import androidx.annotation.NonNull;

import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.SPUtils;
import com.cloud.phone.MainActivity;
import com.cloud.phone.base.BaseApp;
import com.cloud.phone.constants.Constants;
import com.cloud.phone.task.MsgTaskManger;
import com.cloud.phone.task.ProxyTaskManager;
import com.cloud.phone.task.bean.BeAttentionChatBean;
import com.cloud.phone.task.bean.ChatMsgList;
import com.cloud.phone.task.bean.FirstSyncServerData;
import com.cloud.phone.task.bean.MsgTaskBean;
import com.cloud.phone.task.bean.StringResultDataBean;
import com.cloud.phone.task.bean.UserInfo;
import com.cloud.phone.task.taskCongfig.TaskTypeConfig;
import com.cloud.phone.task.tiktok.TikTokTask;
import com.cloud.phone.tools.MyUtils;
import com.cloud.phone.utils.DeviceIDUtil;
import com.cloud.phone.utils.SystemPropertyUtils;
import com.cloud.phone.view.TsUtils;
import com.zhangke.websocket.SocketListener;
import com.zhangke.websocket.WebSocketHandler;
import com.zhangke.websocket.WebSocketManager;
import com.zhangke.websocket.WebSocketSetting;
import com.zhangke.websocket.dispatcher.DefaultResponseDispatcher;
import com.zhangke.websocket.response.ErrorResponse;

import org.greenrobot.eventbus.EventBus;
import org.java_websocket.framing.Framedata;
import org.json.JSONObject;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import okhttp3.OkHttpClient;
import okhttp3.Request;

public class WebsocketUtil {
    MainActivity activity;
    public String TAG = "WebsocketUtil";
    public volatile static WebsocketUtil websocketUtil;
    public WebSocketManager mWebSocketManager;
    public MsgTaskManger msgTaskManger;
    public String currentWebSocketUrl = "";
    public ProxyTaskManager proxyTaskManager;
    public SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");

    public long lastRequestTokenTime;
    public boolean isInit = false;

    public long lastInitHttpConfigTime;

    private Handler mHandler = new Handler(Looper.getMainLooper()); // 全局变量
    private Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            if(mWebSocketManager != null && mWebSocketManager.isConnect()){
                LogUtils.d(TAG,"===发送ping消息给后台===");
                mWebSocketManager.sendPing();
            }
            //20s发送一次ping消息给后台
            mHandler.postDelayed(this, 10 * 1000);
        }
    };


    public static WebsocketUtil getWebsocketUtil() {
        if (websocketUtil == null) {
            websocketUtil = new WebsocketUtil();
        }
        return websocketUtil;
    }


    public String getPhoneId(){
        String phoneId = SystemPropertyUtils.INSTANCE.getSystemProperty("phone.id");
        if (MyUtils.isEmpty(phoneId)) {
            phoneId = "d40d47e2610240db8f0081f20a1dfd80";
        }
        return phoneId;
    }


    public void syncFirstInstallData(){
//        boolean isNotFirstInstall=SPUtils.getInstance().getBoolean("isNotFirstInstall");
//        if(!isNotFirstInstall){
//
//        }
        String phoneId = getPhoneId();
        String requestUrl =
                Constants.HOST_IP + Constants.GET_SYNC_FIRST_DATA_URL + "?id=" + phoneId + "&type=1";
        // 创建 OkHttpClient 对象
        OkHttpClient client =new  OkHttpClient();
        new Thread(){
            @Override
            public void run() {
                try {
                    String response = client.newCall(new Request.Builder()
                                    .url(requestUrl)
                                    .build())
                            .execute()
                            .body()
                            .string();
                    showLog("首次数据：\n请求地址："+requestUrl+"\n响应内容："+response);
                    if(MyUtils.isEmpty(response)){
//                        SPUtils.getInstance().put("isNotFirstInstall",true);
                        return;
                    }
                    JSONObject jsonObject=new JSONObject(response);
                    Integer code= (Integer) jsonObject.get("code");
                    if(Objects.equals(code,0)){
                        FirstSyncServerData firstSyncServerData=GsonUtils.fromJson(response,FirstSyncServerData.class);
                        if(firstSyncServerData.getData()!=null&&firstSyncServerData.getData().getIp()!=null) {
                            firstSyncServerData.getData().initIpConfig();
                            EventBus.getDefault().post(firstSyncServerData);
                        }
                        if(firstSyncServerData.getData()!=null&&!MyUtils.isEmpty(firstSyncServerData.getData().getMsgs())){
                            List<ChatMsgList> list = firstSyncServerData.getData().getMsgs();
                            BeAttentionChatBean beAttentionChatBean=new BeAttentionChatBean();
                            beAttentionChatBean.setBeAttentionChatListBeans(list);
                            SPUtils.getInstance().put(BeAttentionChatBean.class.getSimpleName(),GsonUtils.toJson(beAttentionChatBean));
                        }
//                        SPUtils.getInstance().put("isNotFirstInstall",true);
                    }else{
                        showLog("数据出错了：\n"+response);
                    }
                } catch (Exception e) {
                    try {
                        showLog("获取首次数据出错了："+ e.getMessage());
                        Thread.sleep(10000);
                        syncFirstInstallData();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                }
            }
        }.start();
    }




    public boolean isActivityInTask() {
       if(MainActivity.isInitActivity==1){
           return true;
       }else{
           return false;
       }
    }




    public void init(MainActivity activity) {
        this.activity = activity;
        msgTaskManger = new MsgTaskManger(activity);
        proxyTaskManager = new ProxyTaskManager(activity);
        initHttpConfig();
        isInit = true;
    }


    public synchronized void initHttpConfig(){
        String phoneId = SystemPropertyUtils.INSTANCE.getSystemProperty("phone.id");
        if (MyUtils.isEmpty(phoneId)) {
//                    phoneId = "2b8b58063f744c84a8986759d830dd16";
            //phoneId = "aa1db77b838f421ba28b23fc97d3ffbc";
            // phoneId = "2b8b58063f744c84a8986759d830dd16";
//                    phoneId = "b0c775f12ddd4d88b65f7c35a1c37e20";
//                    phoneId = "db26065b26f44c7892748ff1f165bf9f";
//                      phoneId = "4edaf40b9d434efdb9d225ceb8edfb3f";
//                      phoneId = "59a01ea524664a1d9995960ca3a000cb";
            phoneId = "d40d47e2610240db8f0081f20a1dfd80";
        }
            phoneId = "b0c775f12ddd4d88b65f7c35a1c37e20";
                            Constants.HTTP_FRONT="http://";
                    Constants.HOST_IP= "172.18.6.34:8088";
                    Constants.HOST_PORT_HTTP= "";
                    Constants.HOST_WEBSOCKET_IP= "172.18.6.34";
        String endUrl = "/1"  + "/" + phoneId + "/" + DeviceIDUtil.getDeviceId();
        Constants.BASE_WEB_SOCKET_URL_FRONT = "ws://" + Constants.HOST_WEBSOCKET_IP + ":" + Constants.HOST_WEBSOCKET_PORT;
        currentWebSocketUrl = Constants.BASE_WEB_SOCKET_URL_FRONT + endUrl;
        LogUtils.v("当前连接的webSocket链接地址：" + currentWebSocketUrl);
        showLog("连接Socket地址："+currentWebSocketUrl);
        WebSocketSetting mWebSocketSetting = getWebSocketSetting(currentWebSocketUrl);
        mWebSocketManager = WebSocketHandler.init(mWebSocketSetting);
        connectWebSocket();
    }






    public synchronized void initHttpConfigOld() {
        if(System.currentTimeMillis()-lastInitHttpConfigTime<1000){
            return;
        }
        lastInitHttpConfigTime = System.currentTimeMillis();
        new Thread() {
            @Override
            public void run() {
                String phoneId = SystemPropertyUtils.INSTANCE.getSystemProperty("phone.id");
                if (MyUtils.isEmpty(phoneId)) {
//                    phoneId = "2b8b58063f744c84a8986759d830dd16";
                    //phoneId = "aa1db77b838f421ba28b23fc97d3ffbc";
                   // phoneId = "2b8b58063f744c84a8986759d830dd16";
//                    phoneId = "b0c775f12ddd4d88b65f7c35a1c37e20";
//                    phoneId = "db26065b26f44c7892748ff1f165bf9f";
//                      phoneId = "4edaf40b9d434efdb9d225ceb8edfb3f";
//                      phoneId = "59a01ea524664a1d9995960ca3a000cb";
                      phoneId = "d40d47e2610240db8f0081f20a1dfd80";
                }
//                phoneId = "f7d6044c882644b693f79132eb6bfc65";
                // 创建 OkHttpClient 对象
                OkHttpClient client = new OkHttpClient();
                String finalPhoneId = phoneId;
                // 执行 HTTP 请求
                try {
                    //本地
//                    Constants.HTTP_FRONT="http://";
//                    Constants.HOST_IP= "172.18.6.34:8088";
//                    Constants.HOST_PORT_HTTP= "";
//                    Constants.HOST_WEBSOCKET_IP= "172.18.6.34";

                    String requestUrl = Constants.HOST_IP + Constants.GET_TOKEN_REQUEST_URL + "?id=" + phoneId + "&type=1";
                    LogUtils.e("请求地址：" + requestUrl);
                    Message msg=Message.obtain();
                    msg.obj="token请求地址：\n"+requestUrl;
                    EventBus.getDefault().post(msg);
                    // showTs("地址："+requestUrl);
                    String response = client.newCall(new Request.Builder()
                                    .url(requestUrl)
                                    .build())
                            .execute()
                            .body()
                            .string();
                    if (!MyUtils.isEmpty(response)) {
                        Message msg2=Message.obtain();
                        msg2.obj="token返回数据：\n"+response;
                        EventBus.getDefault().post(msg2);
                        try {
                            StringResultDataBean stringResultDataBean = GsonUtils.fromJson(response, StringResultDataBean.class);
                            if (stringResultDataBean.getCode() != 0) {
                                onRequestFail(String.valueOf(stringResultDataBean.getError()));
                                return;
                            }
                            SPUtils.getInstance().put("token", stringResultDataBean.getData());
                            String endUrl = "/1/" + stringResultDataBean.getData() + "/" + finalPhoneId + "/" + DeviceIDUtil.getDeviceId();
                            Constants.BASE_WEB_SOCKET_URL_FRONT = "ws://" + Constants.HOST_WEBSOCKET_IP + ":" + Constants.HOST_WEBSOCKET_PORT;
                            currentWebSocketUrl = Constants.BASE_WEB_SOCKET_URL_FRONT + endUrl;
                            LogUtils.v("当前连接的webSocket链接地址：" + currentWebSocketUrl);
                            showLog("连接Socket地址："+currentWebSocketUrl);
                            WebSocketSetting mWebSocketSetting = getWebSocketSetting(currentWebSocketUrl);
                            mWebSocketManager = WebSocketHandler.init(mWebSocketSetting);
                            connectWebSocket();
                        } catch (Exception e) {
                            e.printStackTrace();
                            onRequestFail("");
                        }
                    } else {
                        onRequestFail("");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    onRequestFail(e.getMessage());
                }
            }
        }.start();
    }


    public void showLog(String logStr){
        MsgTaskManger.showLog(logStr);
    }


    private void onRequestFail(String message) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                //ToastUtils.showShort("token获取失败");
                SPUtils.getInstance().put("token", "");
                LogUtils.e("获取token失败了！！！" + message);
                String logStr = "token获取失败:" + Constants.HOST_IP + ":" + Constants.HOST_PORT_HTTP + Constants.GET_TOKEN_REQUEST_URL;
                if (MyUtils.isEmpty(Constants.HOST_PORT_HTTP)) {
                    logStr = "token获取失败:" + Constants.HOST_IP + Constants.GET_TOKEN_REQUEST_URL;
                }
                TsUtils.showTips("获取token失败了！！！" + message);
                showLog(logStr);
                //云端系统级应用需要重试获取token
                long betweenTime = System.currentTimeMillis() - lastRequestTokenTime;
                //系统级应用并且两次请求时间超过8秒才会继续安排下一轮请求
                if (Constants.isServiceApplication && betweenTime > 8000) {
                    lastRequestTokenTime = System.currentTimeMillis();
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            initHttpConfig();
                        }
                    }, 10000);
                }
            }
        });
    }






    @NonNull
    private static WebSocketSetting getWebSocketSetting(String currentWebSocketUrl) {
        WebSocketSetting mWebSocketSetting = new WebSocketSetting();
        mWebSocketSetting.setConnectUrl(currentWebSocketUrl);
        //设置连接超时时间
        mWebSocketSetting.setConnectTimeout(10 * 1000);
        //设置心跳间隔时间
        mWebSocketSetting.setConnectionLostTimeout(20);
        //设置断开后的重连次数，可以设置的很大，不会有什么性能上的影响
        mWebSocketSetting.setReconnectFrequency(2);
        //设置消息分发器，接收到数据后先进入该类中处理，处理完再发送到下游
        mWebSocketSetting.setResponseProcessDispatcher(new DefaultResponseDispatcher());
        mWebSocketSetting.setProcessDataOnBackground(true);
        mWebSocketSetting.setReconnectWithNetworkChanged(true);
        return mWebSocketSetting;
    }

    public long lastShowOffline;

    private void connectWebSocket() {
        LogUtils.e(TAG + "===connectUrl===" + currentWebSocketUrl);
        try {
            if(mWebSocketManager==null){
                return;
            }
            mWebSocketManager.addListener(new SocketListener() {
                @Override
                public void onConnected() {
                    LogUtils.e(TAG + "===连接成功====");
                    showLog("socket连接成功");
                    mRunnable.run();
                }

                @Override
                public void onConnectFailed(Throwable throwable) {
                    LogUtils.e(TAG + "===连接失败====");
                    showLog("socket连接失败:" + currentWebSocketUrl);
                }

                @Override
                public void onDisconnect() {
                    LogUtils.e(TAG + "===断开连接====");
                    showLog("socket断开连接");
                }

                @Override
                public void onSendDataError(ErrorResponse errorResponse) {
                    LogUtils.e(TAG + "===发送数据失败====" + errorResponse.getDescription());
                    showLog("发送数据失败--->" + errorResponse.getDescription());
                }

                @Override
                public <T> void onMessage(String msg, T t) {
                    showLog(msg);
                    if (Constants.TASK_IS_RUNNING) {
                        return;
                    }
                    if (msgTaskManger != null) {
                        msgTaskManger.onHandleMsg(msg);
                    }
                    //处理vpn代理和进程守护信息
                    if (proxyTaskManager != null) {
                        proxyTaskManager.onHandleMsg(msg);
                    }
                    mRunnable.run();
                }

                @Override
                public <T> void onMessage(ByteBuffer bytes, T t) {
                    LogUtils.e(TAG + "===接收到消息byteBuffer====");
                    ByteBuffer rBuffer = ByteBuffer.allocate(1024);
                    Charset charset = Charset.forName("UTF-8");
                    try {
                        String receiveText = charset.newDecoder().decode(rBuffer.asReadOnlyBuffer()).toString();
                        LogUtils.e(TAG + "===接收到消息byteBuffer====" + receiveText);
                        if (msgTaskManger != null) {
                            msgTaskManger.onHandleMsg(receiveText);
                        }
                        //处理vpn代理和进程守护信息
                        if (proxyTaskManager != null) {
                            proxyTaskManager.onHandleMsg(receiveText);
                        }
                        showLog(receiveText);
                        mRunnable.run();
                    } catch (CharacterCodingException e) {
                        throw new RuntimeException(e);
                    }
                }

                @Override
                public void onPing(Framedata pingData) {
                    LogUtils.e(TAG + "===心跳onPing===" + pingData);
                }

                @Override
                public void onPong(Framedata framedata) {
                    if(!isActivityInTask()){
                        TsUtils.showTips("云乐多关闭，已自动恢复并激活");
                        AppUtils.launchApp(BaseApp.app.getPackageName());
                    }
                    LogUtils.e(TAG + "===心跳onPong===" + framedata);
                    showLog(format.format(new Date()) + "  | 心跳onPong->"+currentWebSocketUrl);
                }
            });
            mWebSocketManager.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 更新手机内app的各项安装信息
     */
    public void updatePhoneStatus() {
        String userInfoStr = SPUtils.getInstance().getString(UserInfo.class.getSimpleName());
        UserInfo userInfo = null;
        if (!MyUtils.isEmpty(userInfoStr)) {
            userInfo = GsonUtils.fromJson(userInfoStr, UserInfo.class);
        }
        //当前不在tiktok页面且并未安装tiktok，tiktok信息获取结束了
        TikTokTask tiktokTask = new TikTokTask();
        tiktokTask.currentTaskType = TaskTypeConfig.TIKTOK_UPDATE_CURRENT_APP_LOGIN_INFO;
        MsgTaskBean msgTaskBean = tiktokTask.createCurrentUpdateInfo(userInfo, 2,false);
        if (msgTaskBean != null) {
            String jsonData = GsonUtils.toJson(msgTaskBean);
            LogUtils.v("向服务器发送最新获取的信息：");
            LogUtils.v(jsonData);
            //发送消息
            sendMsg(jsonData);
            showLog(jsonData);
        }
    }

    public void sendMsg(String data) {
        if (mWebSocketManager != null) {
            if(!MyUtils.isEmpty(data)&&!data.contains("1005")) {
                showLog(format.format(new Date())+"-发送数据:" + data);
            }
            mWebSocketManager.send(data);
        }
    }
}
